/**
    ATClab - scriptable Air Traffic Control simulations.
    Copyright (C) 2010 openatclab@gmail.com

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
**/

#ifndef __PERFORMANCE_PERFORMANCE_HDR__
#define __PERFORMANCE_PERFORMANCE_HDR__

#ifdef WIN32
	#pragma warning( disable : 4786 )
#endif

#include <utility>
#include <vector>

#define ALT_DATA std::vector< AltitudeData >
#define LEVEL_PAIR std::pair< const AltitudeData *, const AltitudeData * >

namespace performance {

	//
	// performance::PDT
	// performance::PDO
	//
	struct AltitudeData;
	struct PDT;
	struct PDO;


    //
    // performance::performance
    //
    class Performance {

    public:
        Performance( const PDT *, const PDO * );
        ~Performance();

    public:
		double cruising_altitude() const;

		double throttle_setting( double, double ) const;
		double cruise_speed    ( double, double ) const;
		double acceleration    ( double, double ) const;
		double deceleration    ( double, double ) const;
		double climb_speed     ( double, double ) const;
		double climb_rate      ( double, double ) const;
		double descent_speed   ( double, double ) const;
		double descent_rate    ( double, double ) const;

        double ceiling() const;

		double reduced_acceleration_factor() const;
		double maximum_acceleration_factor() const;
		double reduced_deceleration_factor() const;
		double maximum_deceleration_factor() const;

		double acceleration_standard   ( double ) const;
		double deceleration_standard   ( double ) const;
        double climb_speed_minimum     ( double ) const;
        double climb_speed_standard    ( double ) const;
        double climb_speed_maximum     ( double ) const;
        double cruise_speed_minimum    ( double ) const;
        double cruise_speed_standard   ( double ) const;
        double cruise_speed_maximum    ( double ) const;
        double descent_speed_minimum   ( double ) const;
        double descent_speed_standard  ( double ) const;
        double descent_speed_maximum   ( double ) const;
        double climb_rate_reduced      ( double ) const;
        double climb_rate_standard     ( double ) const;
        double climb_rate_accelerated  ( double ) const;
        double climb_rate_maximum      ( double ) const;
        double descent_rate_reduced    ( double ) const;
        double descent_rate_standard   ( double ) const;
        double descent_rate_accelerated( double ) const;
        double descent_rate_maximum    ( double ) const;

        std::pair< double, double > time_distance( double, double ) const;

	private:
		LEVEL_PAIR find_level_data( double ) const;

		double calc_level_value( 
				double,
				LEVEL_PAIR,
				double ( AltitudeData::* )() const
		) const;

		double adjusted_level_value( 
				double, double 
			  , double ( Performance::* )( double ) const
			  , double ( Performance::* )( double ) const
			  , double ( Performance::* )( double ) const
		) const;

		double adjusted_value( double, double, double, double ) const;


    private:
        const PDT *_type;
        const PDO *_data;
	};

	//
	//
	//
	typedef LEVEL_PAIR AltLevelPair;

};

#endif
